<?php
// +----------------------------------------------------------------------
// | Category 类型服务
// +----------------------------------------------------------------------
// | 主要服务于Category数据处理
// +----------------------------------------------------------------------
// | 错误编码头 242xxx
// +----------------------------------------------------------------------

namespace common\service;

use common\exception\LogicException;
use common\model\AttributeModel;
use common\model\AttributeValueModel;
use common\model\StepCategoryAttributeModel;
use Exception;
use support\ErrorCode;
use support\SingletonTrait;

class AttributeService
{
    use SingletonTrait;

    /**
     * 创建属性
     * @param $data
     * @return array
     * @throws \think\Exception
     */
    public function create($data)
    {
        // 处理自定义字段
        $commonService = CommonService::instance("attribute");
        $dealData = $commonService->dealCreateCustomField($data, 'attribute');

        // 执行新增操作
        $attributeModel = model(AttributeModel::class);
        $attributeValueModel = model(AttributeValueModel::class);
        $stepCategoryLinkModel = model(StepCategoryAttributeModel::class);
        $attributeModel->startTrans();//强制开启事务

        try {
            $resData = [];
            $attributeAddData = $attributeModel->addItem($dealData);

            if (!$attributeAddData) {
                if ($attributeModel->getErrorCode() === -411111) {
                    // 存在属性继续添加属性值
                    $attributeData = $attributeModel->field('id,name,code')->where(['name' => $dealData['name']])->find();
                    $attributeId = $attributeData['id'];
                    $attributeName = $attributeData['name'];
                } else {
                    throw new LogicException($attributeModel->getError(), ErrorCode::ATTRIBUTE_ADD_FAILURE);
                }

            } else {
                $attributeId = $attributeAddData['id'];
                $attributeName = $attributeAddData['name'];

                // 写入属性和分类关联
                $stepCategoryLinkAddData = $stepCategoryLinkModel->addItem([
                    'attribute_id' => $attributeId,
                    'step_category_id' => $data['step_category_id'],
                ]);

                if (!$stepCategoryLinkAddData) {
                    throw new LogicException($stepCategoryLinkModel->getError(), ErrorCode::STEP_CATEGORY_LINK_ADD_FAILURE);
                }
            }


            // 写入attribute value 值
            foreach ($data['attribute_values'] as $value) {
                $valItem = [
                    'attribute_id' => $attributeId,
                    'value' => $value['value'],
                    'variable' => $value['variable']
                ];

                $valAddResData = $attributeValueModel->addItem($valItem);

                if (!$valAddResData) {
                    throw new LogicException($attributeValueModel->getError(), ErrorCode::ATTRIBUTE_VALUE_ADD_FAILURE);
                }

                $resData[] = [
                    'id' => $valAddResData['id'],
                    'attribute_name' => $attributeName,
                    'attribute_id' => $valAddResData['attribute_id'],
                    'value' => $value['value'],
                    'variable' => $value['variable']
                ];
            }

            $attributeModel->commit();
            return $resData;
        } catch (\Throwable $e) {
            $attributeModel->rollback();
            throw_strack_exception($e->getMessage(), ErrorCode::ATTRIBUTE_CREATE_FAILURE);
        }
    }

    /**
     * 关联已存在的属性
     * @param $data
     * @return mixed
     */
    public function relation($data)
    {
        $attributeModel = model(AttributeModel::class);
        $stepCategoryLinkModel = model(StepCategoryAttributeModel::class);
        $stepCategoryLinkModel->startTrans();//强制开启事务
        try {
            // 写入属性和分类关联
            $stepCategoryLinkAddData = $stepCategoryLinkModel->addItem([
                'attribute_id' => $data['attribute_id'],
                'step_category_id' => $data['step_category_id'],
            ]);

            if (!$stepCategoryLinkAddData) {
                throw new LogicException($stepCategoryLinkModel->getError(), ErrorCode::STEP_CATEGORY_LINK_ADD_FAILURE);
            }

            //查出关联的属性列表
            $attributeIdData = $attributeModel
                ->alias('attribute')
                ->join("LEFT JOIN attribute_value ON attribute_value.attribute_id = attribute.id")
                ->field('attribute.name as attribute_name,attribute_value.attribute_id,attribute_value.id,attribute_value.value,attribute_value.variable')
                ->where(['attribute.id' => $data['attribute_id']])
                ->select();

            $stepCategoryLinkModel->commit();
            return $attributeIdData;
        } catch (\Throwable $e) {
            $stepCategoryLinkModel->rollback();
            throw_strack_exception($e->getMessage(), ErrorCode::ATTRIBUTE_RELATED_FAILURE);
        }
    }

    /**
     * 获取属性列表
     * @return mixed
     */
    public function getAttributeList($filter = [], $fields = 'id,name,code')
    {
        return model(AttributeModel::class)->where($filter)->field($fields)->cache(C('database.default_query_cache_time'))->select();
    }


    /**
     * 获取指定工序分类的属性列表
     * @param $filter
     * @return array|mixed
     */
    public function getStepCategoryAttributes($filter)
    {
        $stepCategoryLinkModel = model(StepCategoryAttributeModel::class);
        $attributeModel = model(AttributeModel::class);

        $attributeFilter = [];
        if (!empty($filter)) {
            $attributeIdData = $stepCategoryLinkModel->field('attribute_id')->where($filter)->select();
            if (!empty($attributeIdData)) {
                $attributeIds = array_column($attributeIdData, 'attribute_id');
                $attributeFilter = [
                    'attribute.id' => ['IN', join(',', $attributeIds)]
                ];
            } else {
                return [];
            }
        }

        $order = "attribute_value.attribute_id asc,attribute_value.index asc";
        $attributeIdData = $attributeModel
            ->alias('attribute')
            ->join("LEFT JOIN attribute_value ON attribute_value.attribute_id = attribute.id")
            ->field('attribute.name as attribute_name,attribute_value.attribute_id,attribute_value.id,attribute_value.value,attribute_value.variable,attribute.code as attribute_code,attribute_value.index')
            ->where($attributeFilter)
            ->order($order)
            ->select();

        return $attributeIdData;
    }


    /**
     * 删除基础方法
     * @param $filter
     * @return mixed
     * @throws \think\Exception
     * @throws Exception
     */
    public function deleteAttribute($filter)
    {
        $attributeModel = model(AttributeModel::class);
        $attributeValueModel = model(AttributeValueModel::class);
        $stepCategoryAttributeModel = model(StepCategoryAttributeModel::class);

        // 获取当前模块删除主键
        $masterIdData = $attributeModel->field('id')->where($filter)->select();

        if (empty($masterIdData)) {
            throw_strack_exception('Delete item does not exist.', ErrorCode::ATTRIBUTE_DELETE_FAILURE);
        }

        $masterIds = implode(',', array_column($masterIdData, 'id'));
        $count = $stepCategoryAttributeModel->where(['attribute_id' => ['in', $masterIds]])->count();

        if ($count) {
            throw_strack_exception("can`t delete attribute[{$masterIds}]", ErrorCode::ATTRIBUTE_DELETE_FAILURE);
        }
        $attributeModel->startTrans();//强制开启事务
        try {
            $attributeModel->deleteItem(
                [
                    'id' => ['IN', $masterIds]
                ]
            );
            //  删除指定属性值
            $attributeValueModel->deleteItem([
                'attribute_id' => ["IN", $masterIds]
            ]);
            $attributeValueModel->commit();

            return $masterIds;
        } catch (\Throwable $e) {
            $attributeValueModel->rollback();
            throw $e;
        }
    }

    /**
     * 获取指定工序分类 属性树
     * @param $param
     * @return array
     */
    public function getAttributeTree($param)
    {
        $attributeModel = model(AttributeModel::class);
        $stepCategoryAttributeModel = model(StepCategoryAttributeModel::class);
        $stepCategoryAttributeData = $stepCategoryAttributeModel->where($param['filter'])->field('attribute_id')->select();
        $attributeIdData = array_column($stepCategoryAttributeData, 'attribute_id', 'attribute_id');
        // 属性列表
        $attributeList = $attributeModel->field('id,name,code')->where(['id' => ['IN', implode(',', $attributeIdData)]])->select();
        $attributeValueData = model(AttributeValueModel::class)->where(['attribute_id' => ['IN', implode(',', $attributeIdData)]])->select();
        $attributeValueData = array_map(function ($item) {
            $item['real_id'] = $item['id'];
            $item['id'] = 'attribute_value_' . $item['id'];
            $item['name'] = $item['value'];
            return $item;
        }, $attributeValueData);
        $attributeValueData = array_group_by($attributeValueData, 'attribute_id');

        foreach ($attributeList as &$attribute) {
            $attribute['children'] = $attributeValueData[$attribute['id']] ?? [];
            $attribute['real_id'] = $attribute['id'];
            $attribute['id'] = 'attribute_' . $attribute['id'];
        }

        return $attributeList;
    }
}
